Architektur
Bestandteile Eine Softwarearchitektur soll die Struktur des Systems beschreiben. Dies beinhaltet die Komponenten, Schnittstellen und Beziehungen. Die Architektur beschränkt sich auf die essentiellen Bestandteile und eine Gesamtsystemsicht. Sie muss die Balance finden zwischen präziser Beschreibung und Kompaktheit.Kap05 ( ), Seite 16 Die Architektur legt die wesentlichen Entwurfsentscheidungen fest und beschränkt damit die Implementierungsmöglichkeiten. Gleichzeitig erlaubt dies frühzeitige Analysen durch Prototypen und Abschätzungen zu Zeit und Kosten. Durch ihre Abstraktion ist sie möglicherweise für ähnliche Projekte wiederverwendbar.Kap05 ( ), Seite 19 Stakeholder Als Stakeholder werden die Personen(-gruppen) bezeichnet, die direkt oder indirekt am Projekt beteiligt sind. Die Aufgabe des Architekten besteht darin, die Anforderungen der verschiedenen Stakeholder zu berücksichtigen und ein System zu entwerfen, das diesen möglichst gerecht wird.Kap05 ( ), Seite 17 Die Architekturbeschreibung trägt mit ihrer Abstraktion wesentlich zur Kommunikation mit den Stakeholdern bei. Sichten Das System kann aus verschiedenen Aspekten (Sichten) betrachtet werden, um die Anforderungen umzusetzen. So werden bei dem Entwurf eines Hauses mehrere Pläne gezeichnet, die zum Beispiel die Statik des Hauses prüfen oder Wasser- und Stromleitungen planen. Solche unterschiedlichen Sichten werden auch in der Softwarearchitektur eingenommen und bilden gemeinsam die Gesamtspezifikation. Die Herausforderungen hierbei sind die Sicherstellung der Vollständigkeit und der Konstistenz zwischen den Sichten.Kap05 ( ), Seite 29 4+1 Sichten-Modell Im 4+1 Sichten-Modell nach Philippe Kruchten werden 4 Sichten eingeführt, die das System aus Sicht der Stakeholder beschreiben sollen und durch eine zusätzliche Sicht gestützt werden können (daher +1). Es besteht aus der * logischen Sicht für den Endnutzer, * Struktursicht für den Entwickler, * Ablaufsicht für die dynamischen Aspekte, * physikalischen Sicht für die Verteilung bzw. Installation. Die zusätzliche Sicht ist die der Szenarien, die mit beispielhaften Anwendungsfällen die anderen Sichten stützen soll.Kap05 ( ), Seite 31 Es gibt einige verschiedene Diagramme, die zur Notation in den Sichten verwendet werden.Kap05 ( ), Seite 34 Taktiken Zur Verbesserung der Architektur und Eigenschaften eines Systems können verschiedene Taktiken zu Rate gezogen werden. Sie werden typischerweise durch geeignete Muster realisiert.Kap05 ( ), Seite 40 Verfügbarkeit Zur Bestimmung der Verfügbarkeit müssen zunächst zwei Arten von Fehlern unterschieden werden. Ein failure ist ein von außen beobachtbarer Fehler. Ein fault hingegen tritt intern auf und kann gegebenenfalls abgefangen werden, bevor er als failure nach außen sichtbar wird.Kap05 ( ), Seite 41 Zur Bestimmung der Verfügbarkeit eines Systems wird die Zeit ohne Fehler (uptime) in Bezug zu den Reparaturzeiten (downtime) gesetzt. Zur Reparaturzeit werden nicht geplante Wartungsarbeiten gezählt. Die mean time to repair, \text{MTR} , ist die durchschnittliche Reparaturzeit und die mean time to failure, \text{MTF} , die durchschnittliche Zeit zwischen zwei failures abzüglich der Reparaturzeit. Damit ist die Verfügbarkeit definiert als : \frac{\text{MTF}}{\text{MTF}+\text{MTR}}. Zur Verbesserung der Verfügbarkeit muss verhindert werden, dass ein fault zum failure wird. Hierbei gibt es Muster, die bei Fehlererkennung, -behandlung und der erneuten Integration der fehlerhaften Komponenten in das Gesamtsystem. Zur Fehlererkennung können folgende Muster verwendet werden:Kap05 ( ), Seite 42 * Exception: Weiterleitung der Fehlerbehandlung an eine spezielle Komponente * Ping/'Echo': Eine Komponente sendet in regelmäßigen Abständen Nachrichten an alle anderen und kontrolliert deren Antworten. Anhand von fehlerhaften Antworten lassen sich faults erkennen. * Heartbeat: Alle Komponenten müssen regelmäßig Nachrichten zu einer überschauenden Koponente senden. Bei Ausbleiben eines heartbeats liegt möglicherweise in der Komponente ein fault vor. Für die Fehlerbehandlung ist prinzipiell Redundanz nötig. Dazu bieten sich folgende Taktiken an:Kap05 ( ), Seite 43 * Aktive Redundanz: Die Komponenten laufen aktiv parellel. Bei Ausfall einer Komponente ist die andere bereits im Einsatz, es kommt also zu sehr kurzen Verzögerungen. * Passive Redundanz: Die Komponent sind redundant angelegt, jedoch übernimmt nur eine die Interaktion mit dem Restsystem. Die redundanten Komponenten werden fortlaufend aktualisiert. Bei Ausfall der aktiven Komponente springt eine passive ein. ** Spare: Ein redundantes System, das mehrere Komponenten übernehmen kann und dynamisch in Rollen eingesetzt werden kann. Zur Wiedereinführung einer ausgefallenen Komponente gibt es verschiedene Muster:Kap05 ( ), Seite 45 * Schattenoperation: Die Komponente beobachtet zunächst nur das System und vergleicht ihr Verhalten mit den redundanten Komponenten. Nach kurzer Zeit wird sie wieder aktiv in den Betrieb integriert. * Zustands-Resynchronisation: Der Zustand wird von redundanten Komponenten auf die ausgefallene kopiert. Dies kann unter Umständen sehr aufwendig sein. * Checkpoint/Rollback: Es werden periodisch checkpoints erstellt, die den Systemzustand abspeichern. Bei einem fault kann das System in einen solchen Zustand durch einen rollback zurückversetzt werden. Modifizierbarkeit Mit Modifizierbarkeit wird bezeichnet, wie einfach sich Änderungen am System vornehmen lassen. Messen lässt sie sich über die Zeit und Kosten, die für Implementierung, Tests und Ausliefern von Änderungen nötig sind. Erschwert wird die Modifizierbarkeit durch Abhängigkeiten untereinander und mangelnder Lokalisierung der Funktionalität. Dadurch kann ein Ripple-Effekt entstehen, bei dem durch Änderungen an einer Komponente auch andere Komponenten angepasst werden.Kap05 ( ), Seite 46 Verbessern lässt sich zunächst die Modifizierbarkeit von Modulen durch folgende Muster:Kap05 ( ), Seite 47 * Kapselung: Sie bewirkt hohe Kohäsion, indem möglichst wenig öffentliche Schnittstellen angeboten werden und ermöglicht lokale Änderungen, die keinen Einfluss auf andere Module haben. * Reduktion von Verbindungen: Bewirkt geringe Kopplung, indem der Ripple-Effekt verringert wird. * Schnittstellen erhalten: Wenn neue Schnittstellen zusätzlich eingeführt werden, bleibt die Rückwärtskompatibilität erhalten. Ein Nachteil ist die erhöhte Komplexität des Systems. * Vermittler: Je nach Typ der Verbindung bieten sich verschiedene Methoden und Muster an, um die Komplexität der Komponentenverbindungen zu reduzieren. Weiterhin kann die Auswirkung von Änderungen auf das Gesamtsystem reduziert werden durchKap05 ( ), Seite 48 * Kohärenz: Der Erfüllung einer Aufgabe durch genau eine Komponente. * Antizipation: Durch gedankliche Vorstellung möglicher Änderungen kann das System auf seine Kohärenz geprüft werden; falls Änderungen übergreifende Teile des Systems betreffen würden, deutet dies auf eine zu große Kopplung zwischen Komponenten. Die Modifizierbarkeit kann durch Verzögern des Bindungszeitpunkts des Codes verbessert werden. Dazu lassen sich anwenden:Kap05 ( ), Seite 49 * Registrierung zur Laufzeit: Ermöglichen von Plugins. * Konfigurationsdateien: Dies bietet die Möglichkeit zur Rekonfiguration bei Auslieferung oder gar zur Laufzeit. * Polymorphie: Komponenten können zur Laufzeit von abgeleiteten Komponenten ersetzt werden. * Komponentenersetzung: Durch dynamische Zusammenstellung der Komponenten bei Auslieferung können Endnutzer ihr System anpassen. * Standardisierte Protokolle: Sie ermöglichen die Zusammenarbeit unabhängiger Prozesse. Dependency Inversion Principle Dependency Inversion Vorher.svg|Abhängigkeit einer High-Level-Komponente von einer Low-Level-Komponente Dependency Inversion Nachher.svg|Abhängigkeit von einer Abstraktion Das Dependency Inversion Principle verbessert die Modifizierbarkeit insbesondere bei Migration des Systems in eine neue Umgebung. Es besagt, dass Module auf hohen Ebenen nicht von denen unterer Ebenen abhängen sollten. Vielmehr sei eine Abhängigkeit beider von Abstraktionen wie Interfaces empfehlenswert. Außerdem sollten nicht die Abstraktionen von den Details abhängen sondern umgekehrt die Details von den Abstraktionen.Kap05 ( ), Seite 50 Somit lassen sich Änderungen auf tieferen Ebenen vornehmen, die keine Auswirkungen mehr auf Module darüber haben. Dadurch ist die Modifizierbarkeit verbessert. Security Das Problem der software security betrifft das gesamte System auf allen Ebenen. Eine Schutzmaßnahme ist immer nur bei bestimmten Angriffen wirksam und lässt sich häufig nicht kapseln, sondern bezieht sich auf das Gesamtsystem.Kap05 ( ), Seite 51 Das Prinzip Securing the Weakest Link bezeichnet die Notwendigkeit, den schwächsten Teil des Systems zu identifizieren und diesen zu stärken. Da Angreifer nach Möglichkeit die schwächsten Komponenten nutzen, ist das Gesamtsystem nur so stark wie sein „schwächstes Glied“.Kap05 ( ), Seite 53 Mit Failing Securely wird das Verhalten bezeichnet, bei Fehlern keine unsicheren Aktionen zuzulassen. Zum Beispiel sollte bei Auftreten eines Fehlers kein Admin-Interface angezeigt werden, da dies von Angreifern ausgenutzt werden könnte.Rumpe, B. in Vorlesung 2 am 21.10.15, siehe Vorlesungsvideo der Video AG, ab Min. 00:32:29 Durch Economy of Mechanism wird versucht, Sicherheitsmaßnahmen, die bei funktionalen Tests häufig nicht auffallen, dadurch einfacher erkennbar und zuverlässiger zu machen, indem zum einen die Taktik des „keep it simple“ (KISS) angewendet wird und zum anderen Sicherheitsmaßnahmen wie Kryptographie nicht selbst implementiert, sondern wiederverwendet wird.Kap05 ( ), Seite 54 Beim Prinzip Least Privilige werden jedem Nutzer nur die für seine Aufgabe notwendigen Rechte vergeben. Dies dämmt den Schaden ein, den ein Angreifer durch Übernahme einer solchen Rolle anrichten kann. Verweise Referenzen * Rumpe, B.: Vorlesungsfolien SWT.Kap05.Softwareentwurf.Systementwurf ( ) Siehe auch Übersichtsseite von Einführung in die Softwaretechnik